package camid.util.monitoring;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import camid.services.cloudmanager.CloudManagerAgent;

public class MetricEvaluator {

	private String metricName;
	
	private double maxValue;
	
	private double minValue;
	
	private double weight;
	
	private boolean bounded;
	
	private static final Logger logger = LogManager.getLogger(CloudManagerAgent.class.getName());
	
	public MetricEvaluator(String metricName, double weight) {
		super();
		this.metricName = metricName;
		this.weight = weight;
		this.maxValue = 0;
		this.minValue = 0;
		this.bounded = false;
	}
	
	

	public MetricEvaluator(String metricName, double weight, 
			double minValue, double maxValue) {
		super();
		this.metricName = metricName;
		this.maxValue = maxValue;
		this.minValue = minValue;
		this.weight = weight;
		this.bounded = true;
	}



	public String getMetricName() {
		return metricName;
	}

	public void setMetricName(String metricName) {
		this.metricName = metricName;
	}

	public double getWeight() {
		return weight;
	}

	public void setWeight(double weight) {
		this.weight = weight;
	}

	public double getMaxValue() {
		return maxValue;
	}

	public double getMinValue() {
		return minValue;
	}
	
	public double evaluateCostFromMetric(double metricValue)
	{
		double result = 0.0;
		
		if(!bounded)
		{
			updateBounds(metricValue);	
		}
		
		double normalized = normalize(metricValue);
		result = normalized * weight;
		
		logger.info("Metric: " + metricName +" ; Raw = " + metricValue + 
				", Normalized = " + normalized + ", Weighted = " + result);
		
		return result;
	}


	private void updateBounds(double metricValue)
	{
		if(metricValue > this.maxValue)
		{
			this.maxValue = metricValue;
		}
	}
	
	private double normalize(double metricValue) {
		
		
		double denominator = (maxValue == minValue) ?
				1.0 :
				(maxValue - minValue);
		
		double result = metricValue / denominator;		
		return result;
	}
	
	public double evalateMetricFromCost(double cost)
	{
		logger.info("Metric name: " + metricName);
		double unweightedValue = cost / weight;
		logger.info("Cost for balancing: " + cost + "; Cost without weight: " + unweightedValue);
		
		double unormValue = (unweightedValue*(maxValue - minValue) + minValue);
		logger.info("Max: " + maxValue + "; Min: " + minValue + "; Unormalized value: " + unormValue);
		
		return unormValue;
	}
	
	
}
